import type { VNode } from 'vue';
import type { AdDetailFormProps } from '../types/adDetailForm';
import { BasicTableProps, BasicColumn, FetchParams } from '@/components/Table';
import { PageRequest, PageData, FilterGroup, FilterRule } from '#/request';
import { EnumSchema } from '#/common';

import type { ColEx } from '@/components/Form/src/types/index';
import { RenderCallbackParams, ComponentFormSchema } from '@/components/Form';
import { TableActionType } from '@/components/Table/src/types/table';
import { FormModeEnum } from '@/enums/formEnum';

import { FilterOperateEntity } from '@/enums/filterOperateEnum';

/** 查询参数 */
export interface AdFetchParams extends FetchParams {
  /** 搜索信息 */
  searchInfo?: FilterGroup;
}

/** 高级表格选项 */
export interface AdTableProps<T = any> extends BasicTableProps<T> {
  /** 表格数据接口请求对象 */
  api?: (params: PageRequest) => Promise<PageData | any>;
  /** 额外的请求参数 */
  searchInfo?: FilterGroup;
  /** 列配置 */
  columns: AdColumn[];
  /** 序号列配置 */
  indexColumnProps?: BasicColumn;
  /** 操作列配置 */
  actionColumn?: BasicColumn;
  /** 在INPUT组件上单击回车时，是否自动提交 */
  searchFormAutoSubmitOnEnter?: boolean;
  /** 是否在重置时重新发起请求 */
  searchFormSubmitOnReset?: boolean;
  /** 详情表单 */
  detailForm?: AdDetailFormProps;
}

/** 高级表格列 */
export interface AdColumn extends BasicColumn {
  /** 列头显示文字 */
  title?: string;
  /** 列宽度 */
  width?: string | number;
  /** 数据标识 */
  dataIndex?: string;
  /** 表单是否显示，根据这个值决定是否在动态表单架构中显示 */
  formVisible?: boolean;
  /** 表单是否允许编辑，根据这个值决定是否在动态表单架构中可编辑 */
  formEditable?: boolean;
  /** 是否必填 */
  required?: boolean;
  /** 是否允许搜索，根据这个值决定是否列在搜索列选择下拉列表中 */
  filterable?: boolean;
  /** 此列的过滤字段名(用于关联数据查询)
   * @description: 外键联表查询：比如对于 Blog 查询作者昵称，原 Index 为 'UserName'，此值需预设为 'User.UserName'，才能在后端正常查询到数据。
   * @description: 非外键联表查询：比如对于 Blog 查询作者昵称，原 Index 为 'UserName'，此值需预设为 'UserId'，然后配合设置 'filterJoin' 提交后端进行查询。
   */
  filterIndex?: string;
  /** 非外键关联查询，当需要非外键关联查询时，需要设置以配合关联实体查询。 */
  filterJoin?: {
    /** 非外键关联查询的实体类型*/
    entityType: string;
    /** 非外键关联查询的选择字段名 */
    filterField: string;
    /** 非外键关联查询的选择字段名，该字段在后端会自动射关联 'filterIndex'-->'dataIndex' 进行数据过滤。 */
    selectField: string;
  };
  /** 数据类型 */
  dataType?:
    | 'enum'
    | 'integer'
    | 'number'
    | 'quantity'
    | 'price'
    | 'amount'
    | 'rate'
    | 'percentage'
    | 'measure'
    | 'string'
    | 'text'
    | 'password'
    | 'email'
    | 'mobile'
    | 'url'
    | 'ipv4'
    | 'ipv6'
    | 'idcard'
    | 'guid'
    | 'boolean'
    | 'datetime'
    | 'date'
    | 'time'
    | 'array';
  /** 枚举数据 */
  enumData?: EnumSchema[];
  /** 表单架构 */
  formSchema?: ComponentFormSchema;
  /** 表单自定义 */
  formCustomer?: {
    /** 列配置 */
    colProps?: Partial<ColEx>;
    /** 渲染呈现 */
    render?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;
  };
  /** 筛选操作实体集合 */
  entities?: FilterOperateEntity[];
}

/** 高级表格动作类型 */
export interface AdTableActionType extends TableActionType {
  /** 打开详情表单 */
  openDetailForm: (formMode: FormModeEnum, record?: Recordable<any>) => void;
}

/**
 * 处理筛选条件组
 * @param g 处理前的筛选条件组
 * @param cols 高级表格列
 * @returns 处理后的筛选条件组
 */
export function handleFilterGroup(g: FilterGroup, cols: AdColumn[]) {
  if (!g.Operate) {
    return g;
  }
  const group = new FilterGroup();
  group.Operate = g.Operate;
  for (const item of g.Groups) {
    group.Groups.push(handleFilterGroup(item, cols));
  }
  for (const item of g.Rules) {
    let field = item.Field;
    const column = cols.find((m) => m.dataIndex === field);
    field = column?.filterIndex || field;
    const filterRule = new FilterRule(field, item.Value, item.Operate);
    filterRule.JoinEntityType = item.JoinEntityType || column?.filterJoin?.entityType;
    filterRule.JoinFilterField = item.JoinFilterField || column?.filterJoin?.filterField;
    filterRule.JoinSelectField = item.JoinSelectField || column?.filterJoin?.selectField;
    group.Rules.push(filterRule);
  }
  return group;
}
